<template>
  <div class="mouse-track">
    <el-form :inline="true" size="small">
      <el-form-item label="圆环宽度">
        <el-input-number v-model="userSet.weight" :min="1" :max="5" />
      </el-form-item>

      <el-form-item label="最大半径">
        <el-input-number v-model="userSet.radius" :min="20" :max="60" />
      </el-form-item>

      <el-form-item label="变化速度">
        <el-input-number v-model="userSet.speed" :min="1" :max="7" />
      </el-form-item>

      <el-form-item label="颜色变化">
        <el-radio-group v-model="userSet.colorType">
          <el-radio :label="0">
            随机颜色
          </el-radio>
          <el-radio :label="1">
            线性变化
          </el-radio>
        </el-radio-group>
      </el-form-item>
    </el-form>
    <canvas ref="showNode" @mousemove="onMouseMoveFunc" />
  </div>
</template>

<script setup lang="ts">
import { onMounted, ref, watch, onUnmounted, reactive } from 'vue'
import { random } from '@/utils/index'
import globalS from '@/store/global-store'

const localGlobal = globalS()




// const temp = getPageRole(baseRoute.hash)

// console.log(temp);



let delaytimer: NodeJS.Timeout | number

// { name, store }
localGlobal.$onAction(({ name }) => {

  if (name === 'SET_UNFOLD') {

    clearTimeout(delaytimer)

    delaytimer = setTimeout(() => {

      updateScreenSize()

    }, localGlobal.ALIAS_TRANS_TIME + 100)
  }
})

// 有效视觉范围
const validW = ref(0)
const validH = ref(0)

let isDisableFlag: number

const userSet = reactive({
  radius: 45,
  weight: 5,
  speed: 1,
  colorType: 0 // 0-随机 1-线性
})

const currentColor = reactive({
  R: 0,
  rs: 1,

  G: 70,
  gs: 1,

  B: 255,
  bs: 1
})

const showNode = ref<HTMLCanvasElement>()
const showCtx = ref<CanvasRenderingContext2D | null>()

const trackArr = reactive(<Circle[]>[])

watch(
  () => userSet.weight,
  nd => {
    if (!showCtx.value) { return }
    showCtx.value.lineWidth = nd
  }
)

// 圆环
class Circle {

  x: number
  y: number
  color: string
  opacity: number = 1
  radius: number = 3

  constructor(x: number, y: number, color: string) {
    this.x = x
    this.y = y
    this.color = color
  }

  draw() {

    if (!showCtx.value) { return }

    showCtx.value.beginPath()
    showCtx.value.strokeStyle = this.color + this.opacity + ')'
    showCtx.value.arc(this.x, this.y, this.radius, 0, 2 * Math.PI)
    showCtx.value.stroke()

    this.radius += userSet.speed
    this.opacity = (userSet.radius - this.radius) / userSet.radius
  }

}

/** 绘制圆环 */
const loopDraw = () => {

  if (!showCtx.value) { return }

  showCtx.value.fillRect(0, 0, validW.value, validH.value)

  trackArr.forEach(circle => {
    circle.draw()
  })

  if (trackArr[0]?.radius > userSet.radius) {
    trackArr.shift()
  }

  isDisableFlag = requestAnimationFrame(loopDraw)
}

const changeColor = () => {

  // 1-线性变化
  if (userSet.colorType) {

    if (currentColor.R >254 || currentColor.R < 0) { currentColor.rs *= -1 }
    if (currentColor.G >254 || currentColor.G < 0) { currentColor.gs *= -1 }
    if (currentColor.B >254 || currentColor.B < 0) { currentColor.bs *= -1 }

    currentColor.R += currentColor.rs
    currentColor.G += currentColor.gs
    currentColor.B += currentColor.bs

    return
  }

  currentColor.R = random(0, 255)
  currentColor.G = random(0, 255)
  currentColor.B = random(0, 255)
}

const onMouseMoveFunc = ({ offsetX, offsetY } : { offsetX: number, offsetY: number }) => {

  changeColor()
  const localColor = `rgba(${currentColor.R}, ${currentColor.G}, ${currentColor.B}, `
  trackArr.push(new Circle(offsetX, offsetY, localColor))
}


// 更新画布大小
const updateScreenSize = () => {

  if (!showNode.value) { return }
  const { clientHeight, clientWidth } = <HTMLElement>document.querySelector('.mouse-track')
  const { offsetHeight } = <HTMLElement>document.querySelector('.mouse-track > .el-form')

  showNode.value.height = clientHeight - 10 - offsetHeight
  showNode.value.width = clientWidth
  showCtx.value = showNode.value.getContext('2d')

  if (showCtx.value) {
    showCtx.value.lineWidth = userSet.weight
  }

  validW.value = clientWidth
  validH.value = clientHeight
}

onMounted(() => {

  updateScreenSize()

  loopDraw()

})

onUnmounted(() => {
  if (isDisableFlag) {
    cancelAnimationFrame(isDisableFlag)
  }
})

</script>

<style lang="scss" scoped>

canvas {
  border: 1px solid;
}
</style>